package com.diankangwo.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.diankangwo.constant.MessageType;
import com.diankangwo.constant.PayStatus;
import com.diankangwo.dao.*;
import com.diankangwo.distribution.DistributionUtil;
import com.diankangwo.domain.*;
import com.diankangwo.dto.OnlinePayLogDTO;
import com.diankangwo.service.*;
import com.diankangwo.util.GuidUtil;
import com.diankangwo.util.PageSupport;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

@Service
public class WebHookServiceImpl implements WebHookService {
    @Autowired
    private OnlinePayLogService onlinePayLogService;

    @Autowired
    private OnlineRefundLogService onlineRefundLogService;

    @Autowired
    private OnlinePayResultLogService onlinePayResultLogService;

    @Autowired
    private QueryPaymentDAO queryPaymentDAO;

    @Autowired
    private PayManagementService payManagementService;

    @Autowired
    private PayResultService payResultService;

    @Autowired
    private OrderDAO orderDAO;

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private PortDAO portDAO;
    @Autowired
    private PortPayLogDAO portPayLogDAO;

    @Autowired
    private WalletPayLogDAO walletPayLogDAO;
    @Autowired
    private PortSettingDAO portSettingDAO;

    @Autowired
    private DistributionUtil distribution;

    @Autowired
    private DistributionDAO distributionDAO;

    @Autowired
    private MyEarningsDAO myEarningsDAO;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private RefundMoneyDAO refundMoneyDAO;

    @Autowired
    private PropertyDAO propertyDAO;

    @Autowired
    private IntegralDAO integralDAO;

    @Autowired
    private CommodityDAO commodityDAO;

    @Autowired
    private InvitationDAO invitationDAO;


    Logger log = Logger.getLogger(this.getClass());

    public void updateStatus(HttpServletRequest request, JSONObject jsonObj) {

        try {
            // 交易父渠道
            String channel_type = jsonObj.getString("channel_type");
            // 交易子渠道
            String sub_channel_type = jsonObj.getString("sub_channel_type");
            // PAY/REFUND 分别代表支付和退款的结果确认
            String transaction_type = jsonObj.getString("transaction_type");
            // 交易单号，对应支付请求的bill_no或者退款请求的refund_no
            String transaction_id = jsonObj.getString("transaction_id");
            // 交易金额，是以分为单位的整数.对应支付请求的total_fee或者退款请求的refund_fee
            int transaction_fee = 0;
            if (transaction_type.trim().equals("TRANSFER")) {
                log.warn("支付结果无此字段：transaction_fee");
                return;
            } else {
                transaction_fee = jsonObj.getIntValue("transaction_fee");
            }
            // 用一个map代表处理结果的详细信息，例如支付的订单号，金额， 商品信息
            JSONObject message_detail = jsonObj.getJSONObject("message_detail");
            // 附加参数，为一个JSON格式的Map，客户在发起购买或者退款操作时添加的附加信息
            JSONObject optional = jsonObj.getJSONObject("optional");

            // 查询相关记录
            if (transaction_type.toString().trim().equalsIgnoreCase("PAY")) { // 判断是支付订单,更新支付订单记录
                OnlinePayLogDTO paylog = onlinePayLogService.searchLogByBillNo(transaction_id);
                if (paylog.getWebhookStatus() == null) {
                    if (transaction_fee == paylog.getTotalFee()) {
                        if (transaction_fee != (paylog.getTotalFee().intValue())) {
                            log.warn("web hook支付订单异常:" + transaction_id + "，金额不符合，推送金额：" + transaction_fee + "，记录金额：" + paylog.getTotalFee());
                            return;
                        }
                        paylog.setWebhookStatus(PayStatus.success.getName());
                        paylog.setUpdateDate(new Date());
                        paylog.setPayStatus(PayStatus.success.getName());
                        paylog.setUpdateUser("SYSTEM");
                        boolean isOk = onlinePayLogService.saveOrUpdate(paylog);
                        log.info("生成在线支付记录：" + isOk);
                        //修改支付状态
                        boolean isSuccess = updateispay(transaction_id);
                        log.info("修改支付状态：" + isSuccess);
                        Order order = orderDAO.findByOrderNo(transaction_id);
                        if (optional.get("type") != null) {
                            if (order.getType().equals("userget")) {
                                WalletPayLog walletPayLog = walletPayLogDAO.getWalletPayLogByOrderNo(order.getOrderNo());
                                walletPayLog.setUserPayStatus("userWallet");
                                walletPayLog.setPayStatus(PayStatus.success.getName());
                                walletPayLog.setWebhookStatus(PayStatus.success.getName());
                                walletPayLog.setTotalFee(((float) transaction_fee / 100));
                                walletPayLogDAO.saveOrUpdate(walletPayLog);
                                UserInfo user = userDAO.find(userDAO.getUserByUid(order.getUid()).getId());
                                user.setBalance(((float) transaction_fee / 100) + user.getBalance());
                                userDAO.saveOrUpdate(user);
                            } else if (optional.get("type").equals("port")) {
                                Integer portId = 0;
                                if (!optional.get("portId").toString().equals("")) {
                                    portId = Integer.parseInt(optional.get("portId").toString());
                                }

                                Port port = new Port();
                                if (portId != 0) {
                                    portDAO.findByPortId(portId);
                                }
                                PortSetting portSetting = portSettingDAO.findAll().get(0);
                                UserInfo userInfo = userDAO.find(Integer.parseInt(optional.get("userId").toString()));
                                if (!optional.get("portId").toString().equals("")) {
                                    Integer parentid = port.getUserId();
                                    port.setParentId(parentid);
                                    port.setUserId(userInfo.getId());
                                    port.setType("");
                                    port.setSaleing(0);
                                    port.setSource("线上购买");
                                    port.setName(userInfo.getName());
                                    port.setTel(userInfo.getTel());
                                    port.setBuytime(new Date());
                                    port.setId_card(optional.get("idCard").toString());
                                    userInfo.setPort(true);
                                    userInfo.setBalance(userInfo.getBalance() + (float) transaction_fee / 100);
                                    userDAO.saveOrUpdate(userInfo);
                                    portDAO.saveOrUpdate(port);
                                } else {
                                    port.setId_card(optional.get("idCard").toString());
                                    port.setMoney(portSettingDAO.findAll().get(0).getPortPrice());
                                    port.setName(userInfo.getName());
                                    port.setTel(optional.get("tel").toString());
                                    port.setUserId(Integer.parseInt(optional.get("userId").toString()));
                                    port.setMoney(order.getTotalFee() / 100);
                                    port.setTel(optional.get("tel").toString());
                                    port.setPresent_value(portSetting.getPortPrice());
                                    port.setPrice(portSetting.getPortPrice());
                                    port.setShoppingPrice(portSetting.getPortPrice());
                                    port.setPortId(GuidUtil.getGuid());
                                    port.setSource("申请端口");
                                    port.setReviewStatus("未审核");
                                    port = portDAO.saveOrUpdate(port);
                                }
                                //存入端口交易记录
                                PortPayLog portPayLog = new PortPayLog();
                                portPayLog.setDate(new Date());
                                portPayLog.setPortId(port.getId());
                                portPayLog.setPrice(order.getTotalFee());
                                portPayLog.setStates(PayStatus.success.getName());
                                portPayLog.setUserId(Integer.parseInt(optional.get("userId").toString()));
                                portPayLog.setOrderNo(optional.get("orderNo").toString());
                                portPayLog.setType("1");
                                portPayLogDAO.saveOrUpdate(portPayLog);
                            }
                        }
                    } else {
                        log.warn("支付金额不正确！");
                    }
                }
            } else if (transaction_type.toString().trim().equalsIgnoreCase("REFUND")) { // 判断是退款订单,更新退款订单记录
                // OnlineRefundLogDTO refundLog = onlineRefundLogService.searchLogByRefundNo(transaction_id);
                RefundMoney refundMoney = refundMoneyDAO.findByOrderNo(transaction_id);
                if (transaction_fee != refundMoney.getMoney()) {
                    log.warn("web hook退款订单异常:" + transaction_id + "，金额不符合，推送金额：" + transaction_fee + "，记录金额：" + refundMoney.getMoney());
                    return;
                }
//                refundLog.setWewalletPayLoghookStatus(PayStatus.success.getName());
//                refundLog.setUpdateDate(new Date());
//                refundLog.setUpdateUser("SYSTEM");
//                boolean isOk = onlineRefundLogService.saveOrUpdate(refundLog);
                refundMoney.setState(3);
                refundMoney.setUpdateDate(new Date());
                boolean isOk = refundMoneyDAO.saveOrUpdate(refundMoney) == null ? false : true;
                log.info("修改退费记录：" + isOk);
                // 更新退款查询表
                QueryPayment qp = queryPaymentDAO.findbyBillNo(transaction_id);
                qp.setRefunded(true);
                queryPaymentDAO.saveOrUpdate(qp);
                Order order = orderDAO.findByOrderNo(optional.get("orderNo").toString());
                order.setOrderStatus(PayStatus.refundsuccess.getName());
                orderDAO.saveOrUpdate(order);
                UserInfo userInfo = userDAO.getUserByUid(order.getUid());
                Message tdMessage = new Message("您的订单：" + order.getOrderNo() + "已同意退款申请！正在打款！", 1, new Date(), MessageType.order_refundsuccess.getName(), order.getUid(), userInfo.getGetui_cid());
                messageDao.insert(tdMessage);
            } else if (transaction_type.toString().trim().equalsIgnoreCase("TRANSFER")) {
                UserInfo user = userDAO.find(Integer.parseInt(optional.get("userId") + ""));
                if (optional.get("type").equals("commission")) {
                    //2.存入佣金提现交易记录
                    Distribution distribution = new Distribution();
                    distribution.setCreatetime(new Date());
                    distribution.setMoney((float) transaction_fee);
                    distribution.setPrizeuserid(user.getId());
                    distribution.setPrizeusername(user.getUsername());
                    distribution.setTriggeruserid(user.getId());
                    distribution.setType(1);
                    distributionDAO.saveDistribution(distribution);

                    WalletPayLog walletPayLog = walletPayLogDAO.find(Integer.parseInt(optional.get("id") + ""));
                    walletPayLog.setPayStatus(PayStatus.success.getName());
                    walletPayLogDAO.saveOrUpdate(walletPayLog);
                    walletPayLog.setUserPayStatus("commission");
                    user.setCommissionbalance(user.getCommissionbalance() - Integer.parseInt(optional.get("totalFee") + ""));
                    userDAO.saveOrUpdate(user);
                } else {
                    WalletPayLog walletPayLog = walletPayLogDAO.find(Integer.parseInt(optional.get("id") + ""));
                    walletPayLog.setPayStatus(PayStatus.success.getName());
                    walletPayLogDAO.saveOrUpdate(walletPayLog);
                    walletPayLog.setUserPayStatus("userWallet");
                    user.setCommissionbalance(user.getBalance() - Integer.parseInt(optional.get("totalFee") + ""));
                    userDAO.saveOrUpdate(user);
                }

            } else {
                log.info("交易单号未找到：" + transaction_fee);
                return;
            }
            // 添加操作结果日志
            OnlinePayResultLog resultLog = new OnlinePayResultLog();
            resultLog.setBillNo(transaction_id);
            resultLog.setChannel_type(channel_type);
            resultLog.setSub_channel_type(sub_channel_type);
            resultLog.setMessage_detail(message_detail.toJSONString());
            resultLog.setOptional(optional.toJSONString());
            resultLog.setTransaction_fee(transaction_fee);
            resultLog.setTransaction_type(transaction_type);
            onlinePayResultLogService.saveOrUpdate(resultLog);

        } catch (Exception e) {
            log.warn("处理web hook 结果异常:" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 修改支付结果
     * 分销结算
     *
     * @param out_trade_no
     * @return
     */
    public Boolean updateispay(String out_trade_no) {
        try {
            //String out_trade_no = request.getParameter("out_trade_no"); // 商户内部交易号
//            PayManagement payManagement = payManagementService.queryByBillNo(out_trade_no);
            PayResult payresult = new PayResult();// 缴费结果
//            payManagement.setPayState(PayStatus.success.getName());
//            payManagementService.saveOrUpdate(payManagement);

            //改变订单状态
            Order order = orderDAO.findByOrderNo(out_trade_no);
            if (order.getType().equals("userget") || order.getType().equals("userout") || order.getType().equals("port")) {
                order.setOrderStatus(PayStatus.success.getName());
                order.setIsPay("success");
            } else if (order.getType().equals("commodity")) {
                MyEarnings myEarnings = new MyEarnings();
                PortSetting portSetting = portSettingDAO.findAll().get(0);
                UserInfo user = userDAO.getUserByUid(order.getUid());
                user = userDAO.find(user.getParentId());
                myEarnings.setDate(new Date());
                myEarnings.setOrder_id(order.getOrderNo());
                myEarnings.setUid(user.getUid());
                if (portSetting.getCommission() != 0) {
                    Float money = ((float) (order.getTotalFee() / 100) / portSetting.getCommission());
                    myEarnings.setMy_earnings(money);
                    myEarnings.setText("我的客户给我带来收益：" + money + "元！");
                }
                if (user.isPort() && portSetting.getCommission() != 0) {
                    myEarningsDAO.saveOrUpdate(myEarnings);
                }
                //查询所有客户
                PageSupport<Invitation> invitationPageSupport = invitationDAO.findByUid(user.getId(), 1, Integer.MAX_VALUE);
                if (invitationPageSupport != null) {
                    List<Invitation> invitationList = invitationPageSupport.getResultData();
                    for (int i = 0; i < invitationList.size(); i++) {
                        invitationList.get(i).setMy_earnings(myEarnings.getMy_earnings());
                        invitationList.get(i).setSpending_total(invitationList.get(i).getSpending_total() + order.getTotalFee() / 100);
                        invitationDAO.saveOrUpdate(invitationList.get(i));
                    }
                }

                //user.setCommissionbalance(user.getCommissionbalance() + money.intValue());
                userDAO.saveOrUpdate(user);

                order.setOrderStatus(PayStatus.beforedeliver.getName());
                order.setIsPay("success");
                //减去购物车库存
                for (int i = 0; i < order.getShoppingCarts().size(); i++) {
                    //判断库存是否充足
                    JSONArray jsonArray = JSONArray.parseArray(order.getShoppingCarts().get(i).getSelected());
                    for (int j = 0; j < jsonArray.size(); j++) {
                        JSONObject jsonObject = JSONObject.parseObject(jsonArray.get(j).toString());
                        Property property = propertyDAO.find(Integer.parseInt(jsonObject.get("propertiesID").toString()));
                        property.setPropertyNum((Integer.parseInt(property.getPropertyNum()) - order.getShoppingCarts().get(i).getCommodityNumber() + ""));
                        propertyDAO.update(property);
                    }
                }
                Commodity c = commodityDAO.find(order.getShoppingCarts().get(0).getCommodityId());
                if (order.getCouponID() != null && order.getCouponID() == 1) {
                    //可抵用积分
                    float integralTotal = user.getIntegral() / c.getIntegralConsumptionRatio();
                    //最多抵扣积分
                    int integralLimit = c.getIntegralSpendingLimit() / c.getIntegralConsumptionRatio();

                    if (integralTotal > 0) {
                        if (integralLimit > (int) integralTotal) {
                            user.setIntegral(user.getIntegral() - (int) integralTotal * c.getIntegralConsumptionRatio());
                            userDAO.updateUser(user);
                            //存入积分明细
                            Integral integral = new Integral();
                            Timestamp ts = new Timestamp(System.currentTimeMillis());
                            integral.setDate(ts);
                            integral.setMoney(integralTotal * c.getIntegralConsumptionRatio());
                            integral.setText("购买" + c.getCommodityName() + "抵用积分：" + integralTotal * c.getIntegralConsumptionRatio());
                            integral.setUid(user.getUid());
                            integral.setType("0");
                            integralDAO.saveOrUpdate(integral);
//                            user.setIntegral(user.getIntegral() + c.getGetIntegral());
//                            userDAO.updateUser(user);
                            Integral integral1 = new Integral();
                            integral1.setUid(user.getUid());
                            integral1.setDate(ts);
                            integral1.setType("1");
                            integral1.setMoney(c.getGetIntegral());
                            integral1.setText("购买" + c.getCommodityName() + "获得积分：" + c.getGetIntegral());
                            integralDAO.saveOrUpdate(integral1);
                        } else {
                            user.setIntegral(user.getIntegral() - integralLimit * c.getIntegralConsumptionRatio());
                            userDAO.updateUser(user);
                            //存入积分明细
                            Integral integral = new Integral();
                            Timestamp ts = new Timestamp(System.currentTimeMillis());
                            integral.setDate(ts);
                            integral.setType("0");
                            integral.setMoney(integralLimit * c.getIntegralConsumptionRatio());
                            integral.setText("购买" + c.getCommodityName() + "抵用积分：" + integralLimit * c.getIntegralConsumptionRatio());
                            integral.setUid(user.getUid());
                            integralDAO.insert(integral);
//                            user.setIntegral(user.getIntegral() + c.getGetIntegral());
//                            userDAO.updateUser(user);
                            Integral integral1 = new Integral();
                            integral1.setUid(user.getUid());
                            integral1.setDate(ts);
                            integral1.setType("1");
                            integral1.setMoney(c.getGetIntegral());
                            integral1.setText("购买" + c.getCommodityName() + "获得积分：" + c.getGetIntegral());
                            integralDAO.insert(integral1);
                        }
                    }
                }
                if (user.isPort()) {
                    user.setIntegral(user.getIntegral()+c.getGetIntegralport());
                } else {
                    user.setIntegral(user.getIntegral()+c.getGetIntegral());
                }
                userDAO.updateUser(user);
            }
            order = orderDAO.saveOrUpdate(order);
            if (order.getType().equals("commodity")) {
                //分销start
                distribution.distribution(order);
                //分销end
            }
            payresult.setBillNo(out_trade_no);
            payresult.setPayReslut(PayStatus.success.getName());
            payresult.setTotalFee(order.getTotalFee());
            payresult.setPayMethod("Ali-wap");
            payresult.setPayTime(new Date());
            if (order.getShoppingCarts().size() > 0) {
                payresult.setTitle(order.getShoppingCarts().get(0).getCommodityName());
            } else {
                payresult.setTitle("用户充值");
            }
//            payResultService.saveOrUpdate(payresult);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn(e.getMessage());
            return false;
        }
    }


}
